﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.IO.Compression;
using System.Threading;
using System.Web;
using System.Web.Script.Serialization;
using System.Xml;
using ZLibNet;

namespace DZPK
{
    public class RoomConfigManager
    {
        private RoomConfigManager()
        {
        }

        private static RoomConfigManager roomConfig = null;

        public static RoomConfigManager GetRoomConfigInstance()
        {
            if (roomConfig == null)
            {
                roomConfig = new RoomConfigManager();
            }

            return roomConfig;
        }

        //private string ConfigSaveFile = "tableConfig.xml";

        private string TableConfigUrl = @"http://pklx117.17c.cn/data/zh117/0718/tables_zh.data?v=13072210";

        private void SendReadConfig(string tableConfigUrl, string ConfigSaveFile)
        {
            HttpWebRequest request;
            HttpWebResponse response;
            string url = tableConfigUrl;
            request = WebRequest.Create(url) as HttpWebRequest;
            request.Method = @"GET";
            request.UserAgent = @"Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0; Touch)";
            //request.Host = @"pklx117.17c.cn";
            request.Headers.Set(HttpRequestHeader.AcceptLanguage, @"zh-CN");
            request.Headers.Set(HttpRequestHeader.AcceptEncoding, @"gzip, deflate, peerdist");
            request.Headers.Set(@"x-flash-version", @"11,7,700,224");
            request.Headers.Set(@"X-P2P-PeerDist", @"Version=1.1");
            request.Headers.Set(@"X-P2P-PeerDistEx", @"MinContentInformation=1.0, MaxContentInformation=2.0");
            request.Headers.Set(@"DNT", @"1");
            request.Referer = @"http://pklx117.17c.cn/core/TexasMain062511516900.swf";
            request.Accept = @"*/*";
            request.KeepAlive = true;

            using (response = (HttpWebResponse)request.GetResponse())
            {
                int bufsize = 40960;
                long leng = response.ContentLength;

                Stream st = response.GetResponseStream();
                {
                    if (response.ContentEncoding.ToLower().Contains("gzip"))
                    {
                        st = new System.IO.Compression.GZipStream(st, System.IO.Compression.CompressionMode.Decompress);
                    }

                    byte[] buffer = new byte[bufsize];
                    MemoryStream memoryStream = new MemoryStream();

                    int read = st.Read(buffer, 0, bufsize);
                    memoryStream.Write(buffer, 0, read);

                    byte[] bufferDe = new byte[bufsize * 10];
                    bufferDe = ZLibCompressor.DeCompress(buffer);

                    string filename = ConfigSaveFile;
                    FileStream filewriter = new FileStream(filename, FileMode.OpenOrCreate, FileAccess.Write);

                    BinaryWriter bw = new BinaryWriter(filewriter);
                    int len = bufferDe.Length;
                    bw.Write(bufferDe, 0, len);

                    bw.Close();
                    filewriter.Close();

                }
            }
        }

        public void GetTableConfigFile(string configfilename)
        {
            SendReadConfig(TableConfigUrl, configfilename);
        }

        public void ParseTableConfig_V2(string filename, out ConcurrentDictionary<int, Table> tableMap)
        {
            tableMap = new ConcurrentDictionary<int, Table>();

            XmlDocument dom = new XmlDocument();
            dom.Load(filename);

            XmlNode root = dom.SelectSingleNode("content");

            XmlNode tableKey = root.SelectSingleNode("tablesKey");
            string[] keys = tableKey.InnerText.Split('`');

            int nameIndex = -1;
            int tidIndex = -1;
            int maxplayerIndex = -1;
            int minchipsIndex = -1;
            int maxchipsIndex = -1;
            for (int i = 0; i < keys.Length; i++)
            {
                string key = keys[i];
                if (key.Equals("tname", StringComparison.OrdinalIgnoreCase))
                {
                    nameIndex = i;
                }

                if (key.Equals("tid", StringComparison.OrdinalIgnoreCase))
                {
                    tidIndex = i;
                }

                if (key.Equals("tplayermax", StringComparison.OrdinalIgnoreCase))
                {
                    maxplayerIndex = i;
                }

                if (key.Equals("tbuymin", StringComparison.OrdinalIgnoreCase))
                {
                    minchipsIndex = i;
                }

                if (key.Equals("tbuymax", StringComparison.OrdinalIgnoreCase))
                {
                    maxchipsIndex = i;
                }
            }

            XmlNode tables = root.SelectSingleNode("tables");
            string[] contents;
            string[] tids;
            string[] tidInterval;
            int startTid, endTid;
            int playerMaxCount;
            Int64 minbuychips, maxbuychips;
            string tablename;

            foreach (XmlNode tableInfo in tables.SelectNodes("n"))
            {
                contents = tableInfo.InnerText.Split('`');

                tablename = contents[nameIndex];
                playerMaxCount =  Convert.ToInt32(contents[maxplayerIndex]);
                minbuychips = Convert.ToInt64(contents[minchipsIndex]);
                maxbuychips = Convert.ToInt64(contents[maxchipsIndex]);

                tids = contents[tidIndex].Split(',');
                foreach (string tid in tids)
                {
                    tidInterval = tid.Split('-');
                    if (tidInterval.Length != 1 && tidInterval.Length != 2)
                    {
                        throw new Exception("Tid Error");
                    }
                    if (tidInterval.Length == 1)
                    {
                        startTid = endTid = Convert.ToInt32(tidInterval[0]);
                    }
                    else
                    {
                        startTid = Convert.ToInt32(tidInterval[0]);
                        endTid = Convert.ToInt32(tidInterval[1]);
                    }

                    for (int j = startTid; j <= endTid; j++)
                    {
                        Table oInfo = new Table();

                        oInfo.tableIndex = j;
                        oInfo.tableName = tablename;
                        oInfo.maxSeatCount = playerMaxCount;
                        oInfo.minBuyChips = minbuychips;
                        oInfo.maxSeatCount = maxbuychips;

                        tableMap[oInfo.tableIndex] = oInfo;
                    }
                }
            }

            XmlNode serversKey = root.SelectSingleNode("serversKey");
            keys = serversKey.InnerText.Split('`');

            int ipIndex = -1;
            int portIndex = -1;
            tidIndex = -1;
            for (int i = 0; i < keys.Length; i++)
            {
                string key = keys[i];
                if (key.Equals("svip", StringComparison.OrdinalIgnoreCase))
                {
                    ipIndex = i;
                }

                if (key.Equals("svport", StringComparison.OrdinalIgnoreCase))
                {
                    portIndex = i;
                }

                if (key.Equals("tid", StringComparison.OrdinalIgnoreCase))
                {
                    tidIndex = i;
                }
            }

            XmlNode serverList = root.SelectSingleNode("servers");
            string[] serverInfoArr;
            foreach (XmlNode server in serverList.SelectNodes("n"))
            {
                Console.WriteLine(server.InnerText);
                serverInfoArr = server.InnerText.Split('`');

                tids = serverInfoArr[tidIndex].Split(',');
                foreach (string tid in tids)
                {
                    tidInterval = tid.Split('-');
                    if (tidInterval.Length != 1 && tidInterval.Length != 2)
                    {
                        throw new Exception("Tid Error");
                    }
                    if (tidInterval.Length == 1)
                    {
                        startTid = endTid = Convert.ToInt32(tidInterval[0]);
                    }
                    else
                    {
                        startTid = Convert.ToInt32(tidInterval[0]);
                        endTid = Convert.ToInt32(tidInterval[1]);
                    }

                    for (int j = startTid; j <= endTid; j++)
                    {
                        Table oInfo;
                        if (tableMap.TryGetValue(j, out oInfo))
                        {
                            oInfo.serverIP = serverInfoArr[ipIndex];
                            oInfo.serverPort = serverInfoArr[portIndex];
                        }
                    }
                }
            }
        }

        public void ParseTableConfig(string filename, out Dictionary<string, TableInfo> tableMap, out Dictionary<int, ServerInfo> serverMap)
        {
            tableMap = new Dictionary<string, TableInfo>();
            serverMap = new Dictionary<int, ServerInfo>();

            XmlDocument dom = new XmlDocument();
            dom.Load(filename);

            XmlNode root = dom.SelectSingleNode("content");

            XmlNode tableKey = root.SelectSingleNode("tablesKey");
            string[] keys = tableKey.InnerText.Split('`');

            int nameIndex = -1;
            int tidIndex = -1;
            int maxplayerIndex = -1;
            int minchipsIndex = -1;
            int maxchipsIndex = -1;
            for (int i = 0; i < keys.Length; i++)
            {
                string key = keys[i];
                if (key.Equals("tname", StringComparison.OrdinalIgnoreCase))
                {
                    nameIndex = i;
                }

                if (key.Equals("tid", StringComparison.OrdinalIgnoreCase))
                {
                    tidIndex = i;
                }

                if (key.Equals("tplayermax", StringComparison.OrdinalIgnoreCase))
                {
                    maxplayerIndex = i;
                }

                if (key.Equals("tbuymin", StringComparison.OrdinalIgnoreCase))
                {
                    minchipsIndex = i;
                }

                if (key.Equals("tbuymax", StringComparison.OrdinalIgnoreCase))
                {
                    maxchipsIndex = i;
                }
            }

            XmlNode tables = root.SelectSingleNode("tables");
            string[] contents;
            string[] tids;
            string[] tidInterval;
            int startTid, endTid;

            foreach (XmlNode tableInfo in tables.SelectNodes("n"))
            {
                Console.WriteLine(tableInfo.InnerText);

                contents = tableInfo.InnerText.Split('`');
                TableInfo tableinfo = new TableInfo();
                tableinfo.tableName = contents[nameIndex];

                if (tableMap.ContainsKey(tableinfo.tableName))
                {
                    tableinfo = tableMap[tableinfo.tableName];
                }

                tids = contents[tidIndex].Split(',');
                foreach (string tid in tids)
                {
                    tidInterval = tid.Split('-');
                    if (tidInterval.Length != 1 && tidInterval.Length != 2)
                    {
                        throw new Exception("Tid Error");
                    }
                    if (tidInterval.Length == 1)
                    {
                        startTid = endTid = Convert.ToInt32(tidInterval[0]);
                    }
                    else //if (tidInterval.Length == 2)
                    {
                        startTid = Convert.ToInt32(tidInterval[0]);
                        endTid = Convert.ToInt32(tidInterval[1]);
                    }

                    for (int j = startTid; j <= endTid; j++)
                    {
                        tableinfo.tableNumberMap[j] = j;
                    }
                }

                tableMap[tableinfo.tableName] = tableinfo;
            }

            XmlNode serversKey = root.SelectSingleNode("serversKey");
            keys = serversKey.InnerText.Split('`');

            int ipIndex = -1;
            int portIndex = -1;
            tidIndex = -1;
            for (int i = 0; i < keys.Length; i++)
            {
                string key = keys[i];
                if (key.Equals("svip", StringComparison.OrdinalIgnoreCase))
                {
                    ipIndex = i;
                }

                if (key.Equals("svport", StringComparison.OrdinalIgnoreCase))
                {
                    portIndex = i;
                }

                if (key.Equals("tid", StringComparison.OrdinalIgnoreCase))
                {
                    tidIndex = i;
                }
            }

            XmlNode serverList = root.SelectSingleNode("servers");
            string[] serverInfoArr;
            foreach (XmlNode server in serverList.SelectNodes("n"))
            {
                Console.WriteLine(server.InnerText);
                serverInfoArr = server.InnerText.Split('`');
                ServerInfo serverinfo = new ServerInfo();

                serverinfo.serverIP = serverInfoArr[ipIndex];
                serverinfo.serverPort = serverInfoArr[portIndex];

                tids = serverInfoArr[tidIndex].Split(',');
                foreach (string tid in tids)
                {
                    tidInterval = tid.Split('-');
                    if (tidInterval.Length != 1 && tidInterval.Length != 2)
                    {
                        throw new Exception("Tid Error");
                    }
                    if (tidInterval.Length == 1)
                    {
                        startTid = endTid = Convert.ToInt32(tidInterval[0]);
                    }
                    else //if (tidInterval.Length == 2)
                    {
                        startTid = Convert.ToInt32(tidInterval[0]);
                        endTid = Convert.ToInt32(tidInterval[1]);
                    }

                    for (int j = startTid; j <= endTid; j++)
                    {
                        serverMap[j] = serverinfo;
                    }
                }
            }
        }

        public void TestGetTableConfig()
        {
            //SendReadConfig(TableConfigUrl);
            //ParseTableConfig(ConfigSaveFile);
        }
    }
}
